//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES OR INDEMNITIES.
//
//
// (C) Copyright 2006 Marvell International Ltd.
// All Rights Reserved
//
//------------------------------------------------------------------------------
//
//  Header: oal_timer.h
//
//  This header define OAL timer module. Module code implements system ticks,
//  idle/power saving HAL functionality. It is also used by other OAL modules
//  for action or information related to time.
//
//  Interaction with kernel:
//      * Interrupt handler (SYSINTR_RESCHED)
//      * CurMSec
//      * OEMIdle
//      * SC_GetTickCount
//      * pQueryPerformanceFrequency(OALTimerQueryPerformanceFrequency)
//      * pQueryPerformanceCounter(OALTimerQueryPerformanceCounter)
//      * pOEMUpdateRescheduleTime(OALTimerUpdateRescheduleTime)

//  Interaction with other OAL modules:
//      * OALTimerInit
//      * OALTimerEarlyWakeup
//      * OALTimerClearEarlyWakeupInterrupt
//      * OALTimerPerformanceCounterHighUpdate


//  Internal module functions for system with count/compare counters:
//      * OALTimerGetCount
//      * OALTimerSetCount
//      * OALTimerGetCompare
//      * OALTimerSetCompare
//      * OALTimerUpdatePeriod

//
//
#ifndef __OAL_TIMER_H
#define __OAL_TIMER_H

#if __cplusplus
extern "C" {
#endif

//------------------------------------------------------------------------------
//
//  Type:   OAL_TIMER_STATE
//
//  Timer module component control block - it unites all internal module
//  variables which can be used by other OAL modules.
//
//
typedef struct TIMER_CONTEXT{
    UINT32          maxPeriodMSec;      // Maximal timer period in MSec
    UINT32          margin;
    volatile UINT64 curCounts;          // Counts at last system tick
    volatile UINT64 idleCounts;         // Counts for idle
    volatile UINT32 base;
    volatile UINT32 match;
    UINT32          performanceHighPart; // High Part of the high resolution performance counter
    UINT32			perfLowLastRead;
}OAL_TIMER_STATE, *POAL_TIMER_STATE;;

//------------------------------------------------------------------------------
//
//  Extern:  g_oalTimer
//
//  Exports the OAL timer control block. This is global instance of internal
//  timer module variables.
//
extern OAL_TIMER_STATE g_oalTimer;

//------------------------------------------------------------------------------
//
//  Function:  OALTimerInit
//
//
BOOL OALTimerInit();

//------------------------------------------------------------------------------
//
//  Function:  OALTimerIntrHandler
//
//  This function implements timer interrupt handler. Depending on hardware
//  it is called from general interrupt handler (e.g. ARM) or it is used
//  as interrupt handler (e.g. MIPS). It returns SYSINTR value as expected 
//  from interrupt handler.
//
UINT32 OALTimerIntrHandler();

//------------------------------------------------------------------------------
//
//  Function: OALTimerUpdatePeriod
//
//  Update the OS timer by periodMSec
//
//
VOID OALTimerUpdatePeriod(UINT32 periodMSec);


//------------------------------------------------------------------------------
//
//  Function:  OALTimerEarlyWakeup
//  This function is used to early wakeup AP
//
BOOL OALTimerEarlyWakeup( UINT32 earlyCounts );

//------------------------------------------------------------------------------
//
//  Function:  OALTimerEarlyInterrupt
//  this function is used to clear the early wakeup inerrrupt
//
VOID OALTimerClearEarlyWakeupInterrupt();

//------------------------------------------------------------------------------
//
//  Function:   OALCPUIdle
//
//  This function is called to put CPU/SoC to idle state. The CPU/SoC should
//  exit idle state when interrupt occurs. It is called with disabled
//  interrupts. When it returns interrupt must be disabled also.
//
//  This function must be implemented only when OAL OEMIdle implementation is
//  used. The common library contains busy loop implementation which can be
//  used for development.
//  
UINT32 OALCPUIdle(INT32 idleMSec);

//------------------------------------------------------------------------------
//
//  Function:  OALGetTickCount
//
//  This function returns number of 1 ms ticks which elapsed since system boot
//  or reset (absolute value isn't important). The counter can overflow but
//  overflow period should not be shorter then approx 30 seconds. Function 
//  is used in  system boot so it must work before interrupt subsystem
//  is active.
//
UINT32 OALGetTickCount();

//------------------------------------------------------------------------------
//
//  Function:  OALTimerQueryPerformanceFrequency
//
//  This function is exported through pQueryPerformanceFrequency.
//
BOOL OALTimerQueryPerformanceFrequency(LARGE_INTEGER *pFrequency);

//------------------------------------------------------------------------------
//
//  Function:  OALTimerQueryPerformanceCounter
//
//  This function is exported through pQueryPerformanceCounter. It returns
//  high resolution counter value.
//
BOOL OALTimerQueryPerformanceCounter(LARGE_INTEGER *pCounter);


//------------------------------------------------------------------------------
//
//  Function: OALTimerPerformanceCounterHighUpdate
//
//  This function is called by OSCR0 interrrupt handler 
//  update the high-resolution performance counter high part
//
VOID OALTimerPerformanceCounterHighUpdate();


//------------------------------------------------------------------------------
//
//  Function:  OALTimerUpdateRescheduleTime
//
//  This function should be implemented if implementation supports variable
//  tick. It is exported through pOEMUpdateRescheduleTime.
//
VOID OALTimerUpdateRescheduleTime(DWORD time);


//------------------------------------------------------------------------------

#if __cplusplus
}
#endif

#endif
